package com.easyadmin.pro.common.configuration;

import com.easyadmin.pro.common.constants.HttpConstants;
import com.easyadmin.pro.common.filters.AuthenticationTokenFilter;
import com.easyadmin.pro.modules.sys.service.impl.UserDetailServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * packageName com.easyadmin.pro.common.configuration
 *
 * @author 骑着蚂蚁去上天
 * @version JDK 17
 * @className GlobalSecurityConfiguration
 * @date 2024/4/1
 * @description 安全配置
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class GlobalSecurityConfiguration {

    @Resource
    private UserDetailServiceImpl userDetailService;

    @Resource
    private AuthenticationTokenFilter authenticationTokenFilter;

    @Value("${easy-admin-pro.not-login-address}")
    private String NOT_LOGIN_ADDRESS;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.userDetailsService(userDetailService)
                // 无需拦截的地址
                .authorizeHttpRequests(auth -> auth.requestMatchers(NOT_LOGIN_ADDRESS.split(",")).permitAll()
                        // 对其它请求进行认证
                        .anyRequest().authenticated())
                .formLogin(login -> {
                    // 配置自定义登录接口
                    login.loginProcessingUrl(HttpConstants.SYS_MODULE_PATH.concat("/user/login")).permitAll()
                            // 禁用表单登录
                            .disable();
                }).logout(logout -> {
                    // 配置自定义登出接口
                    logout.logoutUrl(HttpConstants.SYS_MODULE_PATH.concat("/user/logout")).permitAll()
                            .disable();
                }).csrf(cs -> cs.disable())
                // 基于token无需session
                .sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                // 关闭缓存
                .headers(header -> header.cacheControl(f -> f.disable()))
                // 禁用http basic认证
                .httpBasic(s -> s.disable())
                // 开启跨域
                .cors(s -> s.disable());
        httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
        return httpSecurity.build();
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }


    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}